package com.itheima.health.service.impl;

import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.pojo.Order;
import com.itheima.health.service.MemberService;
import com.itheima.health.service.OrderService;
import com.itheima.health.service.ReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import java.util.*;

/**
 * 数据报表service
 */
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderService orderService;

    @Autowired
    private MemberService memberService;

    @Override
    public List<Map<String, Object>> findAll() {
        return orderDao.findAll();
    }

    /**
     * 查询会员表
     *
     * @return 返回值为装会员日期和个数的map
     */
    @Override
    public Map<String, List<Object>> getSelectMember() {
        //日期模板
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM");
        //调用自定义方法setectMemberTable
        List<Date> listMemberDate = memberDao.setectMemberTable();
        //记录同月注册会员的人数map
        Map<String, Integer> map = new HashMap<>();
        //循环
        for (Date date : listMemberDate) {
            //将日期对象转化为模板字符串
            String format = simpleDateFormat.format(date);

        /*不使用日期模板的做法：提取date中月份提取出来
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);
        String yearMonth = String.valueOf(year) + "." + String.valueOf(month);
        */
            if (map.containsKey(format)) {
                Integer integer = map.get(format);
                map.put(format, integer + 1);
            } else {
                map.put(format, 1);
            }
        }
        log.info("map集合{}", map);

        //创建list<String> stringDate集合
        List<Object> stringDate = new ArrayList<>();
        //创建中间件集合
        List<String> utilsList = new ArrayList<>();
        //循环map
        for (Map.Entry<String, Integer> s : map.entrySet()) {
            String key = s.getKey();
            //将key封装到map中
            utilsList.add(key);
        }
        log.info("List<String> utilsList集合{}", utilsList);
        //对utilsList集合进行排序
        Collections.sort(utilsList);

        //排序后进行集合复制
        stringDate.addAll(utilsList);
        log.info("list<Object> stringDate集合{}", stringDate);

        //2.list<Object> intNumber集合
        List<Object> intNumber = new ArrayList<>();
        //会员数计数器
        Integer count = 0;
        //循环封装好的stringDate集合根据map的key取出对应的value来封装到intNumber集合中
        for (Object s : stringDate) {
            Integer integer = map.get(s);
            count += integer;
            //添加到集合中
            intNumber.add(count);
            log.info("这个月会员数是{}", count);
        }
        log.info("list<Object> intNumber集合{}", intNumber);
        //为什么使用这多集合来做因为map里key是无序的，而我们想要有序的

        //3.封装方法返回值
        Map<String, List<Object>> member = new HashMap<>();
        member.put("months", stringDate);
        member.put("memberCount", intNumber);
        return member;
    }

    @Override
    public Map<String, Object> getBusinessReportData() {
        //用于封装返回数据
        Map<String, Object> map = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar calendar = Calendar.getInstance();
        String today = sdf.format(calendar.getTime());//今日日期

        calendar.add(Calendar.DATE, -7);
        String week = sdf.format(calendar.getTime());//先前推一周日期

        calendar.add(Calendar.DATE,-23);
        String month = sdf.format(calendar.getTime());//先前推一月日期


        Integer todayNemMember = memberService.getCountByRegTime(today); //今日新增会员数
        Integer totalMember = memberService.getCount();   //总会员数
        Integer  thisWeekNewMember = memberService.getWeekCount(week);//本周新增会员数
        Integer  thisMonthNewMember = memberService.getMonthCount(month);//本月新增会员数
        Integer todayOrderNumber = orderService.getCountToday(today);//今日预约数
        Integer thisWeekOrderNumber = orderService.getCountWeek(week);//本周预约数
        Integer thisMonthOrderNumber = orderService.getCountMonth(month);//本月预约数
        Integer todayVisitsNumber =orderService.getCountTodayVisits(today);//今日到诊数
        Integer  thisWeekVisitsNumber =orderService.getCountWeekVisits(week);//本周到诊数
        Integer  thisMonthVisitsNumber =orderService.getCountMonthVisits(month);//本周到诊数
        //热门套餐 hoteSetmeals封装了套餐名称，被预约个数
        List<Map<String,Object>> hoteSetmeals = orderService.hoteSetmeal();
        Integer count =  orderService.getCount();//总预约数

        BigDecimal countBig = new BigDecimal(count);//总预约数
        for (Map<String, Object> entry : hoteSetmeals) {
            BigDecimal setmealCount = new BigDecimal((Long) entry.get("setmeal_count"));
            BigDecimal proportion= setmealCount.divide(countBig,4, RoundingMode.HALF_UP);//占比
            entry.put("proportion",proportion.doubleValue());
        }

        //封装map
        map.put("reportDate",today);
        map.put("todayNewMember",todayNemMember);
        map.put("totalMember",totalMember);
        map.put("thisWeekNewMember",thisWeekNewMember);
        map.put("thisMonthNewMember",thisMonthNewMember);
        map.put("todayOrderNumber",todayOrderNumber);
        map.put("thisWeekOrderNumber",thisWeekOrderNumber);
        map.put("thisMonthOrderNumber",thisMonthOrderNumber);
        map.put("todayVisitsNumber",todayVisitsNumber);
        map.put("thisWeekVisitsNumber",thisWeekVisitsNumber);
        map.put("thisMonthVisitsNumber",thisMonthVisitsNumber);
        map.put("hotSetmeal",hoteSetmeals);
        return map;
    }
}
